import type { WasherDryerController } from './definition'
import type { Worker } from '@/controller/base/types/worker'
import type { Remote } from '@/controller/base/types/remote'
import { useWorker, useRemote, wrapSafeActions } from '@/controller/base/index'
import { RemoteTypes } from '@/controller/base/remote'
import { createBaseState, BaseGetters, BaseActions, createBaseApplianceControl } from '../BaseAppliance'
import { defineStore } from 'pinia'
import {
  DRYER_PROCESS_PHASE,
  DURATION,
  FINISH_IN_RELATIVE,
  OPERATION_STATES,
  ESTIMATED_TOTAL_PROGRAM_TIME,
  WASHER_STAINS,
  START_IN_RELATIVE,
  WASHER_LOAD_RECOMMENDATION,
  PRESENT,
  WASHER_RINSE_HOLD,
  WASHERDRYER_ORIGINAL_PROGRAM_TIME,
  WASHERDRYER_REFER_TO_PROGRAM,
} from '@/constants/Command'
import { installableContentInfo } from '@/api/appliance'
import { useProgramEffects } from '../common/Program/program'
import {
  createPowerOutageState,
  PowerOutageGetters,
  PowerOutageActions,
  usePowerOutageEffects,
} from '../common/PowerOutage/powerOutage'
import i18n from '@/i18n'
import { useControlState } from '@/controller/BaseAppliance/useControl'

// 洗涤
const WASHER = 'LaundryCare.Washer.Program'

// 洗烘
const WASHERDRYER = 'LaundryCare.WasherDryer.Program'

// 烘干
const DRYER = 'LaundryCare.Dryer.Program'

/**
 * 初始化数据
 */
export const createWasherDryerState: () => WasherDryerController.State = () => ({
  ...createBaseState(),
  ...createPowerOutageState(),
  // 状态
  usingHistoryPrograms: true,
  hasDownloadProgram: false, // 是否有下载程序
  stainValue: '', // 智能除渍
  isRinseHoldPresent: false, // 免排水确认是否处于Present状态
})
export const WasherDryerGetters: WasherDryerController.Getters = {
  ...BaseGetters,
  ...PowerOutageGetters,
  programGroupsConfig() {
    /**
     * 不使用程序分组功能
     *  - 未加载完成
     *  - 洗衣机、干衣机 复用 WasherDryerController 时
     *  - SMM类型
     */
    if (!this._datasource.loaded || this._datasource.type !== 'WasherDryer' || this.isSMM) {
      return null
    }

    return [
      {
        key: WASHER,
        name: i18n.global.t('Appliance.ProgramGroup.WasherDryer.Wash'),
      },
      {
        key: WASHERDRYER,
        name: i18n.global.t('Appliance.ProgramGroup.WasherDryer.WashDry'),
      },
      {
        key: DRYER,
        name: i18n.global.t('Appliance.ProgramGroup.WasherDryer.Dry'),
      },
    ]
  },
  // PLC家电优化 刷新detail时不再查询commands
  syncCommandsWhileDetailLoading() {
    return false
  },
  // PLC家电 OperationState切换后 延迟2s再刷新detail、commands
  refreshDelayTime() {
    return 2000
  },
  // 是否检查启动时间在谷电时间相近范围内
  shouldCheckValleyTimeApproching() {
    const hasRelativeOption =
      this.availableParameter?.options?.some((option) =>
        [START_IN_RELATIVE, FINISH_IN_RELATIVE].includes(option.key)
      ) || false
    // 存在RELATIVE Option 时检查谷电时间
    return hasRelativeOption
  },
  // 需要忽略的调节参数Key
  customIgnoredOptionKeys() {
    return [WASHER_LOAD_RECOMMENDATION]
  },
  customIgnoredDisplayOptionKeys() {
    return this.customIgnoredOptionKeys.concat([WASHERDRYER_ORIGINAL_PROGRAM_TIME, WASHERDRYER_REFER_TO_PROGRAM])
  },
  // 是否强制将【预计xx:xx结束】转换为【预计xx:xx开始】(无programRemaining时会显示【正在计算】)
  transformRelativeOrderForced() {
    return true
  },
}
export const WasherDryerActions: WasherDryerController.Actions = wrapSafeActions<
  WasherDryerController.Store,
  WasherDryerController.Actions
>({
  ...BaseActions,
  ...PowerOutageActions,
  async loadDownloadProgram() {
    const res = await installableContentInfo(this._datasource.haId)
    this.hasDownloadProgram = res.data
  },
})
export const WasherDryerObserve: Remote.Observe<WasherDryerController.Store> = {
  [DRYER_PROCESS_PHASE]: (_, remote) => remote.loadSupportCommands(),
}

/**
 * 组合API
 */
const useStore = defineStore<
  'WasherDryer',
  WasherDryerController.State,
  WasherDryerController.Getters,
  WasherDryerController.Actions
>('WasherDryer', {
  state: createWasherDryerState,
  getters: WasherDryerGetters,
  actions: WasherDryerActions,
})

// 组件使用
export function useWasherDryerControl(): WasherDryerController.Control {
  const store = useStore() as WasherDryerController.Store
  const worker = useWorker(store) as Worker.ApplianceWorker<WasherDryerController.Store>
  const remote = useRemote(store) as Remote.ApplianceRemote<WasherDryerController.Store>
  return { store, worker, remote }
}

// 页面使用
export function createWasherDryerControl(
  control: WasherDryerController.Control = useWasherDryerControl()
): WasherDryerController.Control {
  const { store, worker, remote } = control

  createBaseApplianceControl(control, { remoteType: RemoteTypes.Inhouse })
  const { showControlView } = useControlState(control)

  worker.onLoad(async () => {
    const tasks: Promise<void>[] = [
      // 加载状态
      remote.loadAllStatus(),
      remote.loadAllSetting(),
    ]
    // 显示详情页程序列表时 调用程序列表接口
    if (showControlView.value) {
      tasks.push(store.loadAllPrograms())
    }
    await Promise.all(tasks)
    await store.loadPowerSetting()
  })

  remote.addObserve(WasherDryerObserve)

  useProgramEffects(control)
  // 电源控制 断电命令
  usePowerOutageEffects(control)

  // 智能除渍
  initStainEffects(control)

  useWasherDryerBinding(control)

  return control
}

function initStainEffects(control: WasherDryerController.Control) {
  control.worker.useGetValueBinding('stainValue', {
    key: WASHER_STAINS,
    from: 'detailOption',
  })
}

function useWasherDryerBinding(control: WasherDryerController.Control) {
  const { store, worker } = control

  worker.useGetValueBinding('programRemaining', {
    key: FINISH_IN_RELATIVE,
    from: 'detailOption',
    useMessage: 'ignore',
    shouldPatch: () => store.operationState !== OPERATION_STATES.DELAYED_START,
  })
  worker.useGetValueBinding('programRemaining', {
    key: DURATION,
    from: 'detailOption',
  })
  worker.useGetValueBinding('programRemaining', {
    key: DURATION,
    from: 'event',
    useMessage: 'only',
    shouldPatch: () => store.operationState === OPERATION_STATES.READY,
  })
  worker.useGetValueBinding('programRemaining', {
    key: ESTIMATED_TOTAL_PROGRAM_TIME,
    from: 'detailOption',
    shouldPatch: () =>
      [OPERATION_STATES.RUN, OPERATION_STATES.PAUSE, OPERATION_STATES.DELAYED_START].includes(
        store.operationState as OPERATION_STATES
      ),
  })
  // worker.useGetValueBinding('programRemaining', {
  //   key: REMAINING_PROGRAM_TIME,
  //   from: 'detailOption',
  //   shouldPatch: () => {
  //     if (
  //       store.operationState &&
  //       [OPERATION_STATES.RUN, OPERATION_STATES.PAUSE, OPERATION_STATES.DELAYED_START].includes(store.operationState)
  //     ) {
  //       return false
  //     }
  //     return true
  //   },
  // })
  worker.useGetValueBinding('isRinseHoldPresent', {
    key: WASHER_RINSE_HOLD,
    from: 'event',
    patcher: (patchState, reference) => {
      patchState.isRinseHoldPresent = reference.value === PRESENT
    },
  })
}
